/* 
 * File:   main.c
 * Author: forest
 *
 * Created on 19 listopad 2008, 17:47
 */
#include "common.h"

int port_num;

struct sockaddr_in stAddr, stClientAddr;
struct sockaddr_in new_addr, new_cl_addr; // do nowego gniazda

void handle_request(int nClSock) {
    printf("** Client [%s] connected!\n",
            (char *) inet_ntoa((struct in_addr) stClientAddr.sin_addr));
    int cl_port; // nowy adr portu
    cl_port = port_num + 1;
    char buffer[] = {'s', 'p', 'i', 'e', 'r', 'd', 'a', 'l', 'a', 'j', '\n'};
    itoa(cl_port, &buffer);
    write(nClSock, buffer, strlen( buffer));
   
    close(nClSock);
    int new_sock, new_cl_sock;
    memset(&new_addr, 0, sizeof (struct sockaddr));
    new_addr.sin_family = AF_INET;
    new_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    new_addr.sin_port = htons(cl_port);
 
    /* create a socket */
    new_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (new_sock < 0) {
        fprintf(stderr, "Can't create a socket.\n");
        exit(1);
    }
    int optval=0;
    setsockopt(new_sock, SOL_SOCKET, SO_REUSEADDR, (char*) & optval, sizeof (optval));
    if (bind(new_sock, (struct sockaddr*) & new_addr, sizeof (struct sockaddr)) < 0) {
        fprintf(stderr, "Can't bind a name to a socket in handle.\n");
        exit(1);
    }
    if (listen(new_sock, QUEUE_SIZE) < 0) {
        fprintf(stderr, "Can't set queue size.\n");
    }
    int size = sizeof(struct sockaddr);
    new_cl_sock = accept(new_sock, (struct sockaddr*) & new_cl_addr, &size);
        if (new_cl_sock < 0) {
            fprintf(stderr, "Can't create a connection's socket.\n");
            exit(1);
        }
    //write(new_cl_sock, "siema\n", 5);
    close(new_sock);
    close(new_cl_sock);
    exit(0);
}

int main(int argc, char** argv) {
    //if(argc < 2) { printf("Error! Write down port number\n"); exit(-1); }
    //port_num = atoi(argv[1]);
    port_num = 1234; // do usuniecia - zastapic 2 linijkami powyzej
    signal(SIGINT, sig_int);
    int nSocket, nClientSocket;
    int nFoo = 1, nTmp;

    signal(SIGCHLD, childend);

    /* address structure */
    memset(&stAddr, 0, sizeof (struct sockaddr));
    stAddr.sin_family = AF_INET;
    stAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    stAddr.sin_port = htons(port_num);

    /* create a socket */
    nSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (nSocket < 0) {
        fprintf(stderr, "%s: Can't create a socket.\n", argv[0]);
        exit(1);
    }
    setsockopt(nSocket, SOL_SOCKET, SO_REUSEADDR, (char*) & nFoo, sizeof (nFoo));
    if (bind(nSocket, (struct sockaddr*) & stAddr, sizeof (struct sockaddr)) < 0) {
        fprintf(stderr, "%s: Can't bind a name to a socket.\n", argv[0]);
        exit(1);
    }
    if (listen(nSocket, QUEUE_SIZE) < 0) {
        fprintf(stderr, "%s: Can't set queue size.\n", argv[0]);
    }

    while (1) {
        /* block for connection request */
        nTmp = sizeof (struct sockaddr);
        nClientSocket = accept(nSocket, (struct sockaddr*) & stClientAddr, &nTmp);
        if (nClientSocket < 0) {
            fprintf(stderr, "%s: Can't create a connection's socket.\n", argv[0]);
            exit(1);
        }
        /* connection */
        if (!fork()) handle_request(nClientSocket);
    }

    close(nSocket);
    return (0);
}

